public final class IndexedSprite extends Renderer2D {
	public byte pixels[];
	public int width;
	public int height;
	public int offsetX;
	public int offsetY;
	public int trimWidth;
	private int trimHeight;
	public final int[] pallete;

	public void drawIndexedSprite(int x, int y) {
		x += offsetX;
		y += offsetY;
		int offset = x + y * Renderer2D.width;
		int srcOffset = 0;
		int height = this.height;
		int width = this.width;
		int step = Renderer2D.width - width;
		int srcStep = 0;
		if (y < Renderer2D.topY) {
			int trimHeight = Renderer2D.topY - y;
			height -= trimHeight;
			y = Renderer2D.topY;
			srcOffset += trimHeight * width;
			offset += trimHeight * Renderer2D.width;
		}
		if (y + height > Renderer2D.bottomY) {
			height -= (y + height) - Renderer2D.bottomY;
		}
		if (x < Renderer2D.topX) {
			int trimWidth = Renderer2D.topX - x;
			width -= trimWidth;
			x = Renderer2D.topX;
			srcOffset += trimWidth;
			offset += trimWidth;
			srcStep += trimWidth;
			step += trimWidth;
		}
		if (x + width > Renderer2D.bottomX) {
			int trimWidth = (x + width) - Renderer2D.bottomX;
			width -= trimWidth;
			srcStep += trimWidth;
			step += trimWidth;
		}
		if (!((width <= 0) || (height <= 0))) {
			setPixels(height, Renderer2D.pixels, pixels, step, offset, width, srcOffset, pallete,
			srcStep);
		}
	}

	public void shrink() {
		trimWidth /= 2;
		trimHeight /= 2;
		byte newSize[] = new byte[trimWidth * trimHeight];
		int offset = 0;
		for (int offsetY = 0; offsetY < height; offsetY++) {
			for (int k = 0; k < width; k++) {
				newSize[(k + offsetX >> 1) + (offsetY + this.offsetY >> 1) * trimWidth] = pixels[offset++];
			}
		}
		pixels = newSize;
		width = trimWidth;
		height = trimHeight;
		offsetX = 0;
		offsetY = 0;
	}

	public void trim() {
		if ((width == trimWidth) && (height == trimHeight)) {
			return;
		}
		byte newSize[] = new byte[trimWidth * trimHeight];
		int offset = 0;
		for (int offsetY = 0; offsetY < height; offsetY++) {
			for (int offsetX = 0; offsetX < width; offsetX++) {
				newSize[offsetX + this.offsetX + (offsetY + this.offsetY) * trimWidth] = pixels[offset++];
			}
		}
		pixels = newSize;
		width = trimWidth;
		height = trimHeight;
		offsetX = 0;
		offsetY = 0;
	}

	public void flipHorizontally() {
		byte flippedPixels[] = new byte[width * height];
		int offset = 0;
		for (int offsetY = 0; offsetY < height; offsetY++) {
			for (int offsetX = width - 1; offsetX >= 0; offsetX--) {
				flippedPixels[offset++] = pixels[offsetX + offsetY * width];
			}
		}
		pixels = flippedPixels;
		offsetX = trimWidth - width - offsetX;
	}

	public void flipVertically() {
		byte flippedPixels[] = new byte[width * height];
		int offset = 0;
		for (int offsetY = height - 1; offsetY >= 0; offsetY--) {
			for (int offsetX = 0; offsetX < width; offsetX++) {
				flippedPixels[offset++] = pixels[offsetX + offsetY * width];
			}
		}
		pixels = flippedPixels;
		offsetY = trimHeight - height - offsetY;
	}

	public void adjustColors(int red, int green, int blue) {
		for (int i1 = 0; i1 < pallete.length; i1++) {
			int redOffset = pallete[i1] >> 16 & 0xff;
			redOffset += red;
			if (redOffset < 0) {
				redOffset = 0;
			} else if (redOffset > 255) {
				redOffset = 255;
			}
			int greenOffset = pallete[i1] >> 8 & 0xff;
			greenOffset += green;
			if (greenOffset < 0) {
				greenOffset = 0;
			} else if (greenOffset > 255) {
				greenOffset = 255;
			}
			int blueOffset = pallete[i1] & 0xff;
			blueOffset += blue;
			if (blueOffset < 0) {
				blueOffset = 0;
			} else if (blueOffset > 255) {
				blueOffset = 255;
			}
			pallete[i1] = (redOffset << 16) + (greenOffset << 8) + blueOffset;
		}
	}

	private void setPixels(int height, int pixels[], byte srcPixels[], int step, int offset,
	int width, int srcOffset, int pallette[], int srcStep) {
		int destWidth = -(width >> 2);
		width = -(width & 3);
		for (int i = -height; i < 0; i++) {
			for (int i2 = destWidth; i2 < 0; i2++) {
				byte color = srcPixels[srcOffset++];
				if (color != 0) {
					pixels[offset++] = pallette[color & 0xff];
				} else {
					offset++;
				}
				color = srcPixels[srcOffset++];
				if (color != 0) {
					pixels[offset++] = pallette[color & 0xff];
				} else {
					offset++;
				}
				color = srcPixels[srcOffset++];
				if (color != 0) {
					pixels[offset++] = pallette[color & 0xff];
				} else {
					offset++;
				}
				color = srcPixels[srcOffset++];
				if (color != 0) {
					pixels[offset++] = pallette[color & 0xff];
				} else {
					offset++;
				}
			}
			for (int i3 = width; i3 < 0; i3++) {
				byte color = srcPixels[srcOffset++];
				if (color != 0) {
					pixels[offset++] = pallette[color & 0xff];
				} else {
					offset++;
				}
			}
			offset += step;
			srcOffset += srcStep;
		}
	}

	public IndexedSprite(Archive archive, String archiveName, int requestIndex) {
		Packet data = new Packet(archive.getFile(archiveName + ".dat"));
		Packet index = new Packet(archive.getFile("index.dat"));
		index.offset = data.getUnsignedShort();
		trimWidth = index.getUnsignedShort();
		trimHeight = index.getUnsignedShort();
		int palleteSize = index.getUnsignedByte();
		pallete = new int[palleteSize];
		for (int k = 0; k < palleteSize - 1; k++) {
			pallete[k + 1] = index.get24BitInt();
		}
		for (int id = 0; id < requestIndex; id++) {
			index.offset += 2;
			data.offset += index.getUnsignedShort() * index.getUnsignedShort();
			index.offset++;
		}
		offsetX = index.getUnsignedByte();
		offsetY = index.getUnsignedByte();
		width = index.getUnsignedShort();
		height = index.getUnsignedShort();
		int i1 = index.getUnsignedByte();
		int j1 = width * height;
		pixels = new byte[j1];
		if (i1 == 0) {
			for (int k1 = 0; k1 < j1; k1++) {
				pixels[k1] = data.getByte();
			}
			return;
		}
		if (i1 == 1) {
			for (int l1 = 0; l1 < width; l1++) {
				for (int i2 = 0; i2 < height; i2++) {
					pixels[l1 + i2 * width] = data.getByte();
				}
			}
		}
	}
}
